package com.gmail.hh.flickrj.sample.android;


import java.util.Collection;
import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;

import com.gmail.hh.flickrj.sample.android.fragments.FragmentAddPhoto;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentDetail1;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentDetail2;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentGallery1;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentGallery2;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentGallery3;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentHeaderUser;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentMap;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentMenu;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentContacts;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentPhoto;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentPhotogrid;
import com.gmail.hh.flickrj.sample.android.fragments.FragmentPhotolist;



@SuppressLint("NewApi")
public class FragmentComposer   {
	
	private static final Logger logger = LoggerFactory.getLogger(FragmentComposer.class);

	public final  String VIEWTYPE_STARTSCREEN = "startscreen";
	public final  String VIEWTYPE_PHOTOLIST = "photolist";
	public final  String VIEWTYPE_PHOTOGRID = "photogrid";
	public final  String VIEWTYPE_PHOTO = "photo";
	public final  String VIEWTYPE_MAP = "map";
	public final  String VIEWTYPE_GALLERY1 = "gallery1";
	public final  String VIEWTYPE_GALLERY2 = "gallery2";
	public final  String VIEWTYPE_GALLERY3 = "gallery3";
	public final  String VIEWTYPE_ADDPHOTO = "addphoto";
	public final  String VIEWTYPE_CONTACTS = "contacts";

	
	private Activity mActivity;
	Map<String,Fragment> mDisplayedFragmentsAll = new TreeMap<String, Fragment>();
	Stack<String> mDisplayedViewtypeStack = new Stack<String>();
	String viewTypeActual;

	private FragmentMenu fragMenu;
	private FragmentHeaderUser fragHeaderUser;
	private FragmentPhotolist fragPhotolist;
	private FragmentPhotogrid fragPhotogrid;
	private FragmentDetail1 fragDetail1;
	private FragmentDetail2 fragDetail2;
	private FragmentPhoto fragPhoto;
	private FragmentMap fragMap;
	private FragmentGallery1 fragGallery1;
	private FragmentGallery2 fragGallery2;
	private FragmentGallery3 fragGallery3;
	private FragmentAddPhoto fragAddPhoto;
	private FragmentContacts fragContacts;


	public FragmentComposer(Activity activity) {
		mActivity = activity;
		setupFragments();
	}

	

	private void setupFragments() {

		  FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();

			fragMenu = (FragmentMenu) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentMenu.TAG);
			if (fragMenu == null) {
				fragMenu = new FragmentMenu();
				ft.add(R.id.fragment_container, fragMenu, FragmentMenu.TAG);
			}
			ft.hide(fragMenu);

			fragHeaderUser = (FragmentHeaderUser) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentHeaderUser.TAG);
			if (fragHeaderUser == null) {
				fragHeaderUser = new FragmentHeaderUser();
				ft.add(R.id.fragment_container, fragHeaderUser, FragmentHeaderUser.TAG);
			}
			ft.hide(fragHeaderUser);
			
			fragDetail1 = (FragmentDetail1) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentDetail1.TAG);
			if (fragDetail1 == null) {
				fragDetail1 = new FragmentDetail1();
				ft.add(R.id.fragment_container, fragDetail1, FragmentDetail1.TAG);
			}
			ft.hide(fragDetail1);

			fragDetail2 = (FragmentDetail2) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentDetail2.TAG);
			if (fragDetail2 == null) {
				fragDetail2 = new FragmentDetail2();
				ft.add(R.id.fragment_container, fragDetail2, FragmentDetail2.TAG);
			}
			ft.hide(fragDetail2);

			fragPhoto = (FragmentPhoto) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentPhoto.TAG);
			if (fragPhoto == null) {
				fragPhoto = new FragmentPhoto();
				ft.add(R.id.fragment_container, fragPhoto, FragmentPhoto.TAG);
			}
			ft.hide(fragPhoto);

			fragPhotolist = (FragmentPhotolist) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentPhotolist.TAG);
			if (fragPhotolist == null) {
				fragPhotolist = new FragmentPhotolist();
				ft.add(R.id.fragment_container, fragPhotolist, FragmentPhotolist.TAG);
			}
			ft.hide(fragPhotolist);

			fragPhotogrid = (FragmentPhotogrid) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentPhotogrid.TAG);
			if (fragPhotogrid == null) {
				fragPhotogrid = new FragmentPhotogrid();
				ft.add(R.id.fragment_container, fragPhotogrid, FragmentPhotogrid.TAG);
			}
			ft.hide(fragPhotogrid);

			fragMap = (FragmentMap) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentMap.TAG);
			if (fragMap == null) {
				fragMap = new FragmentMap();
				ft.add(R.id.fragment_container, fragMap, FragmentMap.TAG);
			}
			ft.hide(fragMap);

			fragGallery1 = (FragmentGallery1) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentGallery1.TAG);
			if (fragGallery1 == null) {
				fragGallery1 = new FragmentGallery1();
				ft.add(R.id.fragment_container, fragGallery1, FragmentGallery1.TAG);
			}
			ft.hide(fragGallery1);

			fragGallery2 = (FragmentGallery2) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentGallery2.TAG);
			if (fragGallery2 == null) {
				fragGallery2 = new FragmentGallery2();
				ft.add(R.id.fragment_container, fragGallery2, FragmentGallery2.TAG);
			}
			ft.hide(fragGallery2);

			fragGallery3 = (FragmentGallery3) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentGallery3.TAG);
			if (fragGallery3 == null) {
				fragGallery3 = new FragmentGallery3();
				ft.add(R.id.fragment_container, fragGallery3, FragmentGallery3.TAG);
			}
			ft.hide(fragGallery3);

			fragAddPhoto = (FragmentAddPhoto) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentAddPhoto.TAG);
			if (fragAddPhoto == null) {
				fragAddPhoto = new FragmentAddPhoto();
				ft.add(R.id.fragment_container, fragAddPhoto, FragmentAddPhoto.TAG);
			}
			ft.hide(fragAddPhoto);

			fragContacts = (FragmentContacts) mActivity.getFragmentManager()
					.findFragmentByTag(FragmentContacts.TAG);
			if (fragContacts == null) {
				fragContacts = new FragmentContacts();
				ft.add(R.id.fragment_container, fragContacts, FragmentContacts.TAG);
			}
			ft.hide(fragContacts);


			ft.commit();
	}
	
	
	public void composeViewFromStack() {
		// applied, when back-key is pressed
		String viewTypePrevious = null;
		if ( !mDisplayedViewtypeStack.empty() ) {
			viewTypePrevious = mDisplayedViewtypeStack.pop();
			composeView(viewTypePrevious);
		}
		// quit, when no return possible
		if (viewTypePrevious==null) {
			mActivity.finish();
		}
	}

	
	public void composeView(String viewType) {
			
		  FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
		  // default Animation
	//	  ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
		  
		  
		  // remove all fragments from the view
		  Collection<Fragment> fragmentsAll = mDisplayedFragmentsAll.values();
		  for (Fragment fragment : fragmentsAll)  {
				ft.hide(fragment);
		  }
		  // never clear displayed FragmentsAll because of possible use of return-key
		  
		  
		  // show fragment depending on parameter
		  if (viewType==VIEWTYPE_STARTSCREEN) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragDetail1);
				showAndRememberFragment(ft, fragDetail2);
				mDisplayedViewtypeStack.clear();
		  }
		  
		  if (viewType==VIEWTYPE_PHOTOLIST) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragHeaderUser);
				showAndRememberFragment(ft, fragPhotolist);
				mDisplayedViewtypeStack.clear();
		  }
		  
		  if (viewType==VIEWTYPE_PHOTOGRID) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragHeaderUser);
				showAndRememberFragment(ft, fragPhotogrid);
				mDisplayedViewtypeStack.clear();
		  }


		  if (viewType==VIEWTYPE_MAP) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragMap);
				mDisplayedViewtypeStack.clear();
		  }
		  
		  if (viewType==VIEWTYPE_PHOTO) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragPhoto);
				  // put viewtype on stack for return-key usage
				if (viewTypeActual!=null) {
					  mDisplayedViewtypeStack.push(viewTypeActual);
			  }
		  }
		  
		  if (viewType==VIEWTYPE_GALLERY1) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragGallery1);
				mDisplayedViewtypeStack.clear();
		  }

		  if (viewType==VIEWTYPE_GALLERY2) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragGallery2);
				mDisplayedViewtypeStack.clear();
		  }
		  
		  if (viewType==VIEWTYPE_GALLERY3) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragGallery3);
				mDisplayedViewtypeStack.clear();
		  }

		  
		  if (viewType==VIEWTYPE_ADDPHOTO) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragAddPhoto);
				mDisplayedViewtypeStack.clear();
		  }

		  
		  if (viewType==VIEWTYPE_CONTACTS) {
				showAndRememberFragment(ft, fragMenu);
				showAndRememberFragment(ft, fragContacts);
				mDisplayedViewtypeStack.clear();
		  }
		  
		  
		  // commit!
		  ft.commit();
	  	  
		  // remember new view as actual view
		  viewTypeActual = viewType;

	}


	
	private void showAndRememberFragment(FragmentTransaction ft, Fragment fragment) {
		ft.show(fragment);
		mDisplayedFragmentsAll.put(fragment.getClass().getName(), fragment);
	}



// setter / getter
	public FragmentMenu getFragMenu() {
		return fragMenu;
	}
	public FragmentHeaderUser getFragHeaderUser() {
		return fragHeaderUser;
	}
	public FragmentPhotolist getFragPhotolist() {
		return fragPhotolist;
	}
	public FragmentPhotogrid getFragPhotogrid() {
		return fragPhotogrid;
	}
	public FragmentPhoto getFragPhoto() {
		return fragPhoto;
	}
	public FragmentMap getFragMap() {
		return fragMap;
	}
	public FragmentGallery1 getGragGallery1() {
		return fragGallery1;
	}
	public FragmentGallery2 getGragGallery2() {
		return fragGallery2;
	}
	public FragmentGallery3 getGragGallery3() {
		return fragGallery3;
	}
	public FragmentAddPhoto getFragmentAddPhoto() {
		return fragAddPhoto;
	}
	public FragmentContacts getFragmentContacts() {
		return fragContacts;
	}
	
	public String getViewTypeActual() {
		return viewTypeActual;
	}

	
	
	
}
